package net.killerscape.model;

import net.killerscape.util.globalevents.IncreaseStats;

import java.util.Arrays;

public class SkillLevel {
	private Player player;
	
	private int numSkills = 21;
	private int[] skillXP = new int[numSkills];
	private int[] skillLevel = new int[numSkills];
    
    private int[] restoreRates = new int[numSkills];
    private int[] restoreTimers = new int[numSkills];
    private int prayerDepreciationRate = -1;

    private IncreaseStats increaseStats;

    public void setPrayerDepreciationRate(int rate) {
        prayerDepreciationRate = rate;   
    }

    public int getPrayerDepreciationRate() {
        return prayerDepreciationRate;
    }

    public void setRestoreRate(int rate, int skill) {
        restoreRates[skill] = rate;
    }

    public int getRestoreRate(int skill) {
        return restoreRates[skill];
    }

    public void increaseStat(int skill) {
        restoreTimers[skill] += 30;
        if(restoreTimers[skill] >= restoreRates[skill]) {
            if(skillLevel[skill] < getLevelForExp(skillXP[skill])) {
                skillLevel[skill]++;
                sendLevel(skill);
            }
            restoreTimers[skill] = 0;
        }
    }

    public void increaseStats() {
        for(int i = 0; i < numSkills; i++)
            if(i != PRAYER)
                increaseStat(i);
    }

	/*
	 * Starts a new instance of SkillLevel with default values (level = 1, xp = 0)
	 */
	public SkillLevel(Player p) {
		player = p;
        increaseStats = new IncreaseStats(p, 30000);
        World.getWorld().getDelayedEventHandler().add(increaseStats);
		Arrays.fill(skillXP,0);
		Arrays.fill(skillLevel,1);
        Arrays.fill(restoreRates, 60);
        Arrays.fill(restoreTimers, 0);
	}

    public void terminate() {
        increaseStats.terminate();
    }
	
	/*
	 * Returns the players current level for a specific skill (not the max)
	 */
	public int getCurrentLevel(int stat) {
		return skillLevel[stat];
	}
	
	/*
	 * Returns the players max level for a specific skill
	 */
	public int getSkillLevel(int stat) {
		return getLevelForExp(skillXP[stat]);
	}
	
	/*
	 * Reset specific skill level back to max
	 */
	public void resetLevel(int stat) {
		skillLevel[stat] = getLevelForExp(skillXP[stat]);
		sendLevel(stat);
	}
	
	/*
	 * Sets the XP and the max level accordingly of specific skill
	 */
	public void setLevelAndExpBasedOnExp(int stat, int exp) {
		skillLevel[stat] = getLevelForExp(exp);
		skillXP[stat] = exp;
		sendLevel(stat);
	}
	
	/*
	 * Sets the max level and the xp accordingly of specific skill
	 */
	public void setExpAndLevelBasedOnLevel(int stat, int level) {
		skillXP[stat] = getExpForLevel(level);
		skillLevel[stat] = level;
		sendLevel(stat);
	}
	
	/*
	 * Reset all skill levels back to their max (based on xp)
	 */
	public void resetLevels() {
		for(int i = 0; i < numSkills; i++) {
			skillLevel[i] = getLevelForExp(skillXP[i]);
		}
		sendAllLevels();
	}
	
	/*
	 * Send all skill levels & exp to the client. Does not reset current levels to max though.
	 */
	public void sendAllLevels() {
		for(int i = 0; i < numSkills; i++)
			player.getActionSender().sendStat(i, skillLevel[i], skillXP[i]);
	}
	
	/*
	 * Send a particular skill to the client. Does not reset the current level to max.
	 */
	public void sendLevel(int stat) {
		player.getActionSender().sendStat(stat,skillLevel[stat],skillXP[stat]);
	}
	
	/*
	 * Find exp needed for a given level.
	 */
	public int getExpForLevel(int level) {
		int points = 0;
		int output = 0;

		for (int lvl = 1; lvl <= level; lvl++) {
			points += Math.floor((double)lvl + 300.0 * Math.pow(2.0, (double)lvl / 7.0));
			if (lvl >= level)
				return output;
			output = (int)Math.floor(points / 4);
		}
		return 0;
	}
	
	/*
	 * Calculate the level given for a certain exp.
	 */
	public int getLevelForExp(int exp) {
		for(int i = 1; i <= 99; i++) {
			if(getExpForLevel(i) >= exp)
				return i;
		}
		return 0;
	}
	
	public static final int ATTACK = 0,
							DEFENCE = 1,
							STRENGTH = 2,
							HITPOINTS = 3,
							RANGED = 4,
							PRAYER = 5,
							MAGIC = 6,
							COOKING = 7,
							WOODCUTTING = 8,
							FLETCHING = 9,
							FISHING = 10,
							FIREMAKING = 11,
							CRAFTING = 12,
							SMITHING = 13,
							MINING = 14,
							HERBLORE = 15,
							AGILITY = 16,
							THIEVING = 17,
							SLAYER = 18,
							FARMING = 19,
							RUNECRAFTING = 20;
}
